package cn.nzcong.jpress.addon.articlesync.platform;

import cn.nzcong.jpress.addon.articlesync.common.Constant;
import cn.nzcong.jpress.addon.articlesync.common.Exception.AuthException;
import cn.nzcong.jpress.addon.articlesync.common.Exception.ExternalServiceException;
import cn.nzcong.jpress.addon.articlesync.common.Exception.InternalServiceException;
import cn.nzcong.jpress.addon.articlesync.common.util.HttpUtil;
import cn.nzcong.jpress.addon.articlesync.enums.PlatformEnum;
import cn.nzcong.jpress.addon.articlesync.vo.PlatformVerifyVo;
import cn.nzcong.jpress.addon.articlesync.vo.config.CsdnConfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.HashKit;
import io.seata.common.util.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Csdn博客平台
 *
 * @author zecong.nian
 */
public class PlatformCsdn extends BasePlatform<CsdnConfig> {

    @Override
    public PlatformEnum getPlatformEnum() {
        return PlatformEnum.CSDN_BLOG;
    }

    @Override
    public PlatformVerifyVo doVerify(CsdnConfig config) {
        boolean isValid = true;
        String reason = "";
        String userId = "";
        String nickname = "";
        try{
            if(config == null){
                throw new AuthException("账号配置为空");
            } else if(!config.isEnable()){
                throw new AuthException("配置未开启");
            }
            String username = config.getUsername();
            if(username == null){
                throw new AuthException("用户ID未设置");
            }
            if(StringUtils.isBlank(config.getCookie())){
                throw new AuthException("cookie未设置");
            }
            JSONObject respObj = this.getUserInfo(config);
            String respUsername = respObj.getString("username");
            if(!username.equals(respUsername)){
                throw new AuthException("cookie对应账号为：%s", respUsername);
            }
            userId = String.valueOf(respUsername);
            nickname = respObj.getString("nickname");
        } catch (AuthException e){
            isValid = false;
            reason = e.getMessage();
        }
        return PlatformVerifyVo.builder()
                .enable(config.isEnable())
                .isValid(isValid)
                .reason(reason)
                .platformName(getPlatformEnum().getName())
                .platformDisplayName(getPlatformEnum().getDisplayName())
                .userId(userId)
                .nickname(nickname)
                .build();
    }

    @Override
    protected void _doPublishArticle(String title, String article, String author, String tags, String categories) {
        try {
            Long oldId = getOldArticle(title);
            oldId = publish(oldId, title, article, "",false);
            publish(oldId, title, article, "", true);
        } catch (UnsupportedEncodingException e) {
            throw new InternalServiceException(e, "发布失败");
        }
    }

    @Override
    protected String _doUploadImg(String imgLocalUrl) {
        String respStr = HttpUtil.httpPost("https://blog-console-api.csdn.net/v1/image/transfer", new HashMap<>(), getHttpHeader(),
                JSON.toJSONString(new HashMap<String, String>(){{
                    put("uuid", HashKit.md5(imgLocalUrl));
                    put("url", imgLocalUrl);
                }}));
        JSONObject resp = JSONObject.parseObject(respStr);
        if(200 != resp.getIntValue("code") || !resp.containsKey("data")){
            throw new ExternalServiceException("上传图片失败");
        }
        return resp.getJSONObject("data").getString("img_url");
    }

    private Map<String, String> toHttpHeader(CsdnConfig config){
        return new HashMap<String, String>(){{
            put("cookie", "UserName=" + config.getUsername() + ";" + config.getCookie());
        }};
    }

    private Map<String, String> getHttpHeader(){
        return this.toHttpHeader(super.getConfigObj());
    }

    public String upload(String imgLocalUrl){
        return _doUploadImg(imgLocalUrl);
    }

    private JSONObject getUserInfo(CsdnConfig config){
        String respStr = HttpUtil.httpGet("https://me.csdn.net/api/user/show",
                Collections.EMPTY_MAP, this.toHttpHeader(config));
        try {
            JSONObject respObj = JSONObject.parseObject(respStr);
            JSONObject data = respObj.getJSONObject("data");
            if(data == null || data.isEmpty()){
                throw new ExternalServiceException("DSDN verify: user is Emmpty - %s", respStr);
            }
            return data;
        } catch (Exception e){
            throw new AuthException("账号失效：cookie已失效");
        }
    }

    //
    private Long getOldArticle(String title){
        String respStr = HttpUtil.httpGet("https://blog-console-api.csdn.net/v1/article/list?pageSize=20", new HashMap<String, Object>(){{
            put("keyword", title);
        }}, getHttpHeader());
//        Elements es = Jsoup.parseBodyFragment(html).select("p.article-list-item-txt a");
//        Iterator<Element> iterator = es.iterator();
//        while(iterator.hasNext()){
//            //<a href="/postedit/103907547" target="_blank" title="编辑">文章标题</a>
//            Element el = iterator.next();
//            if(title.equalsIgnoreCase(el.html())){
//                String[] href = el.attr("href").split("/");
//                return Long.valueOf(href[href.length - 1]);
//            }
//        }
        JSONObject resp = JSONObject.parseObject(respStr);
        if(resp.getInteger("code") != 200 && !resp.containsKey("data")){
            return null;
        }
        JSONArray list = resp.getJSONObject("data").getJSONArray("list");
        if(list == null || list.size() < 1){
            return null;
        }
        for(Object o : list){
            JSONObject item = (JSONObject)o;
            if(title.equalsIgnoreCase(item.getString("Title"))){
                return item.getLong("ArticleId");
            }
        }
        return null;
    }

    private Long publish(Long pgcId, String title, String contant, String markdownContant, boolean isPublish) throws UnsupportedEncodingException {
        String respStr = HttpUtil.httpPost("https://blog-console-api.csdn.net/v1/postedit/saveArticle",
                new HashMap<>(),  getHttpHeader(), JSONObject.toJSONString(new HashMap<String, String>(){{
            put("title", title);
            put("content", contant);
            put("markdowncontent", markdownContant);
            put("article_id", pgcId == null ? "" : String.valueOf(pgcId));
            put("readtype", "public");
            put("type", "1");
            put("not_auto_saved", "1");
            put("authorized_status", "false");
            put("status", isPublish ? "0" : "1");
//            put("level", "0");
            put("categories", "");
            put("tags", "");
            put("original_link", "");
        }}));
        JSONObject resp = JSONObject.parseObject(respStr);
        if(resp == null || resp.isEmpty() || resp.getIntValue("code") != 200 || resp.getJSONObject("data") == null){
            throw new ExternalServiceException((isPublish ? "发布" : "保存草稿") + "失败 - " + resp.getString("msg"));
        }
        return resp.getJSONObject("data").getLong("article_id");
    }


}
